package com.hww.v2_mtfsdk.utils.camera;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.UnsupportedEncodingException;

public class FaceMarkSurface extends SurfaceView implements SurfaceHolder.Callback {
    protected SurfaceHolder surfaceHolder;
    protected Context context;
    private int width, height;

    private Paint faceRectLinePaint;//人脸框画笔
    private TextPaint textPaint;//人名画笔
    private float textAvail = 0;

    public FaceMarkSurface(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        getHolder().addCallback(this);
        setZOrderOnTop(true);
//        setZOrderMediaOverlay(true);
//        getHolder().setFormat(PixelFormat.TRANSPARENT);
        getHolder().setFormat(PixelFormat.TRANSLUCENT);//将surfaceView背景设置透明

        faceRectLinePaint = new Paint();
        faceRectLinePaint.setAntiAlias(true);
        faceRectLinePaint.setStrokeWidth((float) 4);
        faceRectLinePaint.setStyle(Paint.Style.STROKE);
        faceRectLinePaint.setColor(Color.RED);

        textPaint = new TextPaint();
        textPaint.setColor(Color.parseColor("#FFFFFF"));
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(true);
        textPaint.setShadowLayer(2, 4, 4, Color.parseColor("#267100"));
        textPaint.setTextSize(26);
        textAvail = textPaint.measureText("Harry James Potter");
    }

    public void surfaceCreated(SurfaceHolder holder) {
        surfaceHolder = holder;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        this.width = width;
        this.height = height;
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        surfaceHolder = null;
    }

    public boolean hasDrawInfo = false;

    public void clearDrawInfo() {
        if (surfaceHolder != null && hasDrawInfo) {
            hasDrawInfo = false;
            SurfaceHolder holder = surfaceHolder;
            try {
                Canvas canvas = holder.lockCanvas();
                if (canvas != null) {
                    canvas.drawColor(0, PorterDuff.Mode.CLEAR);
                    holder.unlockCanvasAndPost(canvas);
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (null != holder) {
                    holder.unlockCanvasAndPost(null);
                }
            } catch (Throwable th) {
                if (null != holder) {
                    holder.unlockCanvasAndPost(null);
                }
            }
        }
    }

    public void drawInfo(Rect rect, int w, int h, boolean isMirroring) {
        if (surfaceHolder == null) return;
        if (rect == null) return;

        hasDrawInfo = true;
        SurfaceHolder holder = surfaceHolder;
        Canvas canvas = null;
        try {
            canvas = holder.lockCanvas();
            if (canvas != null) {
                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
                Rect rectSurface = getFitRect(rect, w, h, isMirroring);
                drawRect(canvas, rectSurface);
                holder.unlockCanvasAndPost(canvas);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (canvas != null) {
                holder.unlockCanvasAndPost(canvas);
            }
        } catch (Throwable th) {
            if (canvas != null) {
                holder.unlockCanvasAndPost(canvas);
            }
        }
    }

    private void drawRect(Canvas canvas, Rect rectSurface) {
        if (canvas == null) return;
        if (rectSurface == null) return;
        int lineLength = (rectSurface.right - rectSurface.left) / 4;
        //画人脸框
        canvas.drawLine(rectSurface.left, rectSurface.top, rectSurface.left + lineLength, rectSurface.top, faceRectLinePaint);
        canvas.drawLine(rectSurface.left, rectSurface.top, rectSurface.left, rectSurface.top + lineLength, faceRectLinePaint);

        canvas.drawLine(rectSurface.right - lineLength, rectSurface.top, rectSurface.right, rectSurface.top, faceRectLinePaint);
        canvas.drawLine(rectSurface.right, rectSurface.top, rectSurface.right, rectSurface.top + lineLength, faceRectLinePaint);

        canvas.drawLine(rectSurface.left, rectSurface.bottom - lineLength, rectSurface.left, rectSurface.bottom, faceRectLinePaint);
        canvas.drawLine(rectSurface.left, rectSurface.bottom, rectSurface.left + lineLength, rectSurface.bottom, faceRectLinePaint);

        canvas.drawLine(rectSurface.right, rectSurface.bottom - lineLength, rectSurface.right, rectSurface.bottom, faceRectLinePaint);
        canvas.drawLine(rectSurface.right - lineLength, rectSurface.bottom, rectSurface.right, rectSurface.bottom, faceRectLinePaint);
    }

    private void drawName(Canvas canvas, Rect rectSurface, String name) {
        if (canvas == null) return;
        if (rectSurface == null) return;
        if (name == null) return;
        float nameLength = 0;
        try {
            nameLength = name.getBytes("utf-8").length;
        } catch (UnsupportedEncodingException e) {
            nameLength = name.length();
        }
        if (nameLength >= 18) {
            textPaint.setTextSize(24);
            name = (String) TextUtils.ellipsize(name, textPaint, textAvail, TextUtils.TruncateAt.END);
        } else if (nameLength >= 12) {
            textPaint.setTextSize(26);
        } else {
            textPaint.setTextSize(30);
        }
        canvas.drawText(name, rectSurface.centerX() - (textPaint.measureText(name) / 2.0f), rectSurface.top + 3, textPaint);
    }

    /**
     * 把人脸检测的Rect，根据Surface的实际大小进行调整
     *
     * @param rect        人脸检测的Rect
     * @param dataWidth   图像的实际宽度
     * @param dataHeight  图像的实际高度
     * @param isMirroring 是否需要将人脸框左右镜像   true需要进行镜像    false不需要进行镜像
     * @return 调整后的新Rect
     */
    private Rect getFitRect(Rect rect, int dataWidth, int dataHeight, boolean isMirroring) {
        if (rect == null) return null;
        Rect result = new Rect();
        result.left = (rect.left * width / dataWidth);
        result.right = (rect.right * width / dataWidth);
        //如果摄像头实际回调画面非镜像，而预览画面镜像，则左右翻转人脸框
        if (isMirroring) {
            int left = result.left;
            result.left = width - result.right;
            result.right = width - left;
        }
        result.top = rect.top * height / dataHeight;
        result.bottom = rect.bottom * height / dataHeight;
        return result;
    }
}
